package com.open.capacity.exam.service.impl;

import com.open.capacity.common.exception.service.ServiceException;
import com.open.capacity.common.model.ExamPaperQuestion;
import com.open.capacity.common.model.SysUser;
import com.open.capacity.common.util.PageUtil;
import com.open.capacity.common.web.PageResult;
import com.open.capacity.common.web.Result;
import com.open.capacity.exam.dao.PaperDao;
import com.open.capacity.exam.dao.PaperQuestionDao;
import com.open.capacity.exam.dao.PaperUserDao;
import com.open.capacity.exam.dao.QuestionDao;
import com.open.capacity.exam.feign.GroupFeignClient;
import com.open.capacity.exam.service.PaperService;
import com.open.capacity.exam.vo.PaperVo;
import com.open.capacity.exam.vo.QuestionsVo;
import com.open.capacity.exam.vo.PaperConditionParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

@Service
public class PaperServiceImpl implements PaperService {
    @Autowired
    private PaperDao paperDao;
    @Autowired
    private QuestionDao questionDao;
    @Autowired
    private PaperQuestionDao paperQuestionDao;
    @Autowired
    private GroupFeignClient groupFeignClient;
    @Autowired
    private PaperUserDao paperUserDao;


    /**
     * 模糊查询考卷
     * @param param
     * @return
     */
    @Override
    public PageResult<PaperVo> findPaper(Map<String, Object> param) {
        PageUtil.pageParamConver(param,false);
        //查询所有考卷
        List<PaperVo> list= paperDao.selectAll(param);
        int count= paperDao.selectAllCount(param);
        return PageResult.<PaperVo>builder().data(list).count((long)count).build();
    }

    /**
     * 查询对应考卷的考题
     * @param expaid
     * @return
     */
    @Override
    public PageResult<QuestionsVo> findPaperQuestions(Integer expaid) {
        List<QuestionsVo> eqs=new ArrayList<>();//存放考题数据
        //根据考卷的id查询考题的id
        List<ExamPaperQuestion> list = paperQuestionDao.select(expaid,null);
        for(ExamPaperQuestion epq:list){
            QuestionsVo eqv=new QuestionsVo();
            eqv.setQuesid(epq.getQuesid());

            List<QuestionsVo> sigleEq = questionDao.findAll(eqv);
            QuestionsVo questionsVo = sigleEq.get(0);
            questionsVo.setScore(epq.getScore());
            eqs.add(questionsVo);
        }
        return PageResult.<QuestionsVo>builder().data(eqs).build();
    }

    /**
     * 生成考卷
     * @param examPaper
     * @return
     */
    @Override
    @Transactional
    public Result addPaper(PaperVo examPaper) {
        int count=0;
        Integer insert = paperDao.insert(examPaper);    //插入考卷信息
        if(insert>0){
            Integer expaid = examPaper.getExpaid();
            Map<String,Object> param=new HashMap<>();
            param.put("grouid",examPaper.getGrouid());
//            param.put("page",0);
//            param.put("limit",999999);
            PageResult<SysUser> userList = groupFeignClient.selectUserByGroup(param);   //获取参考小组成员
            List<SysUser> data = userList.getData();
            for(SysUser user:data){
                Integer insertPU=paperUserDao.insert(expaid,user.getId());      //插入参考人和试卷关系数据
                if(insertPU>0){
                    count++;
                }
            }
            if(count==data.size()){
                return Result.succeed("新增成功");
            }else {
                throw new ServiceException("操作失败");
            }
        }else {
            throw new ServiceException("操作失败");
        }

    }

    /**
     * 删除试卷，同时删除试卷考题关系表，试卷和用户关心表
     * @param expaid
     * @return
     */
    @Override
    @Transactional
    public Result removePaper(Integer expaid) {
        //删除试卷信息
        Integer del=paperDao.delete(expaid);
        if(del>0){
            //删除考卷考题关系
            paperQuestionDao.delete(expaid);
            //删除考卷考生关系
            paperUserDao.delete(expaid);
            return Result.succeed("删除成功");
        }
        return Result.failed("操作失败");
    }

    /**
     * 向考卷中添加考题
     * @param params
     * @return
     */
    @Override
    @Transactional
    public Result addPaperQue(List<PaperConditionParam> params) {
        for(PaperConditionParam param:params){
            QuestionsVo examQuestionsVo=new QuestionsVo();
            examQuestionsVo.setStage(param.getStage());
            examQuestionsVo.setTypeid(param.getTypeid());
            examQuestionsVo.setSubjid(param.getSubjid());
            //按要求查询考题
            List<QuestionsVo> data = questionDao.findAll(examQuestionsVo);
            //需要添加的数量
            Integer num = param.getNum();
            Integer score=param.getCountScore()/num;
            //存放考题id的集合
            List<Integer> list=new ArrayList<>();
            //考题数不足
            if(num>data.size()){
                return Result.failed("考题数目不足");
            }else if(num==data.size()){
                //数量相同
                for (QuestionsVo eqv:data) {
                    list.add(eqv.getQuesid());
                }
            }else {                                         //大于需求
                int[] random = getRandom(num,data.size());  //获取随机数
                for(int i:random){
                    Integer quesid = data.get(i).getQuesid();
                    //将生成的考题放入集合
                    list.add(quesid);
                }
            }
            Integer expaid = param.getExpaid();
            for(Integer quesid:list){
                //插入试卷的考题信息
                int insert= paperQuestionDao.insert(expaid,quesid,score);
            }
        }
        return Result.succeed("添加成功");
    }

    /**
     * 获取不重复的随机数
     * @param size 随机数数量
     * @param max 随机数范围0~size
     * @return
     */
    public  int[] getRandom(int size,int max){
        int [] arr =new int[size];
        Random random = new Random();
        int j;
        int num = 0;
        boolean flag;
        for (int i = 0; i < size;) {
            num = random.nextInt(max);
            flag = false;
            for (j = 0; j < i; j++) {
                if (arr[j] == num) {
                    flag = true;
                    break;
                }
            }
            if(!flag) {
                arr[i] = num;
                i++;
            }
        }
        return arr;
    }

}
